home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / lib / tex / inputs / vdm.sty < prev    next >
Encoding:
Text File  |  1991-05-21  |  37.1 KB  |  1,213 lines

  1. %
  2. %    VDM documentstyle option for LaTeX
  3. %
  4. %    M. Wolczko 
  5. %
  6. %    Created from the ashes of VDM.tex and CBJ's vdm86.tex
  7. %
  8. %    Uses the AMS msym fonts if available: if you don't have them,
  9. %    follow the instructions near the string FONT-CUSTOMIZING.
  10. %
  11. %    $Log:    vdm.doc,v $
  12. %    Revision 2.5  88/03/25  18:52:29  mario
  13. %    Improved use of AMS fonts.
  14. %    Improved efficiency by eliminating unnecessary macros.
  15. %    Enable line breaks after underscores in math mode.
  16. %    Fixed used of penalties....were in wrong placeto have any effect.
  17. %    Added \uniqueval, \cons, formbox environment, \R
  18. %    Fixed composite environments so that they can be used in horizontal
  19. %    mode.
  20. %    Fixed a bug in the proof environment.
  21. %
  22. %    Revision 2.4  87/11/12  12:31:07  mario
  23. %    Shortened lines for network mailers,
  24. %    Changed mathcodes of digits,
  25. %    Added \Rat, changed \DEF, added betweenFunctionAndPre hook,skip,
  26. %    and penalty, added \Conc
  27. %
  28. %    Revision 2.3  87/02/26  11:36:07  miw
  29. %    Absence of a blank line after \end{vdm} now forces \noindent.
  30. %    Can now have pre- and post-conditions in function defns.
  31. %    Added \mapinto macro.
  32. %
  33. %    Revision 2.2  86/12/18  12:00:17  miw
  34. %    Added \@changeMathmodeCatcodes to \begin{vdm} to avoid as many
  35. %    catcode problems with @ and _ as possible.
  36. %    Fixed a bug in \If (was adding extra blank lines).
  37. %    Added the \nexists macro.
  38. %    Added the *-form of fn (which had been inadvertently omitted).
  39. %    Fixed a bug in the proof environment (had a name clash with latex).
  40. %    
  41. %    Revision 2.1  86/11/24  13:08:34  miw
  42. %    **** MAJOR REWRITE/EXTENSION ****
  43. %    
  44. %    Entry to the vdm env now is a no-op!
  45. %    No mathcode changes to get the right letters in math mode.
  46. %    Double quotes now delimit text in math mode.
  47. %    \baselineskip within vdm mode is now \VDMbaselineskip.
  48. %    Added the \amssy font.
  49. %    Vertical VDM things (ops, fns, etc) shouldn't need blank lines
  50. %    around them. 
  51. %    Let the user choose whether some things are left- or right-aligned.
  52. %    Added *-forms of quantifiers.
  53. %    Added composite env and \scompose.
  54. %    Added proof env.
  55. %    
  56. %    Revision 1.8  86/10/08  14:11:36  miw
  57. %    Changed \or, \rd, \wr to \Or, \Rd, \Wr.
  58. %    Changed keyword font to sans-serif.
  59. %    Changed \makeNewKeyword to use \newcommand.
  60. %    Added \where keyword.
  61. %    Changed \Nat, \Int, \Bool, \Real to use `blackboard' font.
  62. %    Added `Strachey brackets' using \term.
  63. %    Added function composition, \compf.
  64. %    Added a *-form to the fn environment to omit parens on args.
  65. %    Added a *-form to \LambdaFn to place body on a new line.
  66. %    Added \min and \max monadic operators.
  67. %    Changed \serd and \busd to \rres and \rsub.
  68. %    Added \const for constants.
  69. %
  70. %    Revision 1.7  86/08/14  17:52:32  miw
  71. %    Fixed bugs in vdmfn and vdmop.
  72. %    Moved the pre..Hooks in operations and functions to occur earlier
  73. %    (allows one to change baselineskip).
  74. %
  75. %    Revision 1.6  86/06/03  12:23:05  miw
  76. %    Added the formula env, and fixed a bug in \type.
  77. %    
  78. %    
  79. %    Revision 1.5  86/05/07  17:51:48  miw
  80. %    Parameterised more vertical skips.  Changed many dimensions from pts
  81. %    to exs.  Fixed a bug in \type.  Altered externals so that field names
  82. %    are flush right.
  83. %    
  84. %    Revision 1.4  86/04/17  11:09:04  miw
  85. %    Tweaked some more.
  86. %
  87. %    Revision 1.3 86/03/14 20:44:22 miw
  88. %    Added left margin control with \VDMindent.
  89. %    Tweaked some penalties (esp. \hyphenpenalty)---first use of a
  90. %    \discretionary in quantified expresssion.
  91. %    Fixed a bug in IndentedPara (using box0 instead of copy0)
  92. %    
  93. %    Revision 1.2  86/03/12  16:26:23  miw
  94. %    Changed the fn env. and \Cases.  Added \@raggedRight.
  95. %    Fixed lots of other minor things.
  96. %
  97. %    Revision 1.1  86/03/03  18:42:40  miw
  98. %    Initial revision
  99. %
  100. %
  101. %    $Header: vdm.doc,v 2.5 88/03/25 18:52:29 mario Locked $
  102. %
  103. %
  104. %
  105. %----------------------------------------------------------------
  106. %
  107. %    Installation-dependent features
  108. %
  109. % FONT-CUSTOMIZING
  110. \newif\ifams@
  111. \ams@true  % change to \ams@false if you don't have the AMS fonts
  112. %\ams@false  % change to \ams@true if you have the AMS fonts
  113.  
  114. \newif\ifps@ \ps@false % PostScript-based
  115.  
  116. \def\@fmtname{lplain}
  117. \def\@psfmtname{pslplain}
  118.  
  119. \def\@testcmsy{\if@usecmsy \else 
  120.   \@latexerr{Can't use vdm with this PSLaTeX}%
  121.     {This PSLaTeX does not have the CMSY symbols
  122.     available, and cannot be used with VDM style.  Get
  123.     a guru to rebuild PSLaTeX with the CMSY and CMMI
  124.     fonts included.}\fi}
  125. \def\@testcmmi{\if@usecmmi \else
  126.   \@latexerr{Can't use vdm with this PSLaTeX}%
  127.     {This PSLaTeX does not have the CMMI symbols
  128.     available, and cannot be used with VDM style.  Get
  129.     a guru to rebuild PSLaTeX with the CMSY and CMMI
  130.     fonts included.}\fi}
  131.  
  132. \ifx\fmtname\@fmtname % standard LaTeX is OK
  133. \else \ifx\fmtname\@psfmtname \global\ps@true \@testcmsy \@testcmmi
  134.       \else \ams@false \fi\fi % don't use AMS for SliTeX
  135.  
  136. \newfam\msxfam
  137. \newfam\msyfam
  138.  
  139. \ifams@
  140.     % this is lifted from amssymbols.sty
  141.     \ifcase\@ptsize
  142.      \font\tenmsx=msxm10
  143.      \font\sevenmsx=msxm7
  144.      \font\fivemsx=msxm5
  145.      \font\tenmsy=msym10
  146.      \font\sevenmsy=msym7
  147.      \font\fivemsy=msym5
  148.     \or
  149.      \font\tenmsx=msxm10 scaled \magstephalf
  150.      \font\sevenmsx=msxm8
  151.      \font\fivemsx=msxm6
  152.      \font\tenmsy=msym10 scaled \magstephalf
  153.      \font\sevenmsy=msym8
  154.      \font\fivemsy=msym6
  155.     \or
  156.      \font\tenmsx=msxm10 scaled \magstep1
  157.      \font\sevenmsx=msxm8
  158.      \font\fivemsx=msxm6
  159.      \font\tenmsy=msym10 scaled \magstep1
  160.      \font\sevenmsy=msym8
  161.      \font\fivemsy=msym6
  162.     \fi
  163.  
  164.     \textfont\msxfam=\tenmsx  \scriptfont\msxfam=\sevenmsx
  165.       \scriptscriptfont\msxfam=\fivemsx
  166.     \textfont\msyfam=\tenmsy  \scriptfont\msyfam=\sevenmsy
  167.       \scriptscriptfont\msyfam=\fivemsy
  168.  
  169.     \def\hexnumber@#1{\ifnum#1<10 \number#1\else
  170.      \ifnum#1=10 A\else\ifnum#1=11 B\else\ifnum#1=12 C\else
  171.      \ifnum#1=13 D\else\ifnum#1=14 E\else
  172.      \ifnum#1=15 F\fi\fi\fi\fi\fi\fi\fi}
  173.     \def\msx@{\hexnumber@\msxfam}
  174.     \def\msy@{\hexnumber@\msyfam}
  175. \fi
  176.  
  177. %----------------------------------------------------------------
  178. %
  179. %    The vdm environment
  180. %
  181. \def\vdm{\@changeMathmodeCatcodes\@postUnderPenalty10000 }
  182.  
  183. % after an \end{vdm} the next paragraph is not indented unless a \par
  184. % comes first
  185. \def\endvdm{\global\let\par=\@undonoindent
  186.   \global\everypar={{\setbox0=\lastbox}\global\everypar={}%
  187.             \global\let\par=\@@par}}
  188.  
  189. \def\@undonoindent{\global\everypar={}\global\let\par=\@@par\@@par}
  190.  
  191. %-----------------------------------------------------------------
  192. %
  193. %     Controlling line and page breaks
  194. % Text within the vdm environment is essentially mathematical in
  195. % nature, so requires special care.  Whenever outer vertical mode is
  196. % entered, the \@beginVerticalVDM command should be used.  This sets
  197. % up \leftskip, \rightskip, \baselineskip, \lineskip and
  198. % \lineskiplimit to conform with the overall style.
  199. %
  200. % When entering unrestricted horizontal mode, the \@beginHorizontalVDM
  201. % command should be used.  This sets up:
  202. %    \leftskip and \rightskip to 0,
  203. %    \\ to do line breaking
  204. %    ragged right line breaking, with special penalties, and
  205. %    enters math mode.
  206. % \@endHorizontalVDM should be called when leaving unrestricted
  207. % horizontal mode.
  208.  
  209. \def\@beginVerticalVDM{\@changeMargins\@changeBaselineskip}
  210.  
  211. \def\@beginHorizontalVDM{\@restoreLineSeparator
  212.   \@restoreMargins\@raggedRight\noindent$\strut\relax}
  213. \def\@endHorizontalVDM{\relax\strut$}
  214.  
  215. % \VDMindent is used for \leftskip within VDM, \VDMrindent for
  216. % \rightskip, \VDMbaselineskip for \baselineskip
  217. \newdimen\VDMindent \VDMindent=\parindent
  218. \newdimen\VDMrindent \VDMrindent=\parindent
  219. \def\VDMbaselineskip{\baselineskip}
  220.  
  221. \def\@changeMargins{\leftskip=\VDMindent \rightskip=\VDMrindent}
  222. \def\@restoreMargins{\advance\hsize by-\leftskip
  223.   \advance\hsize by-\rightskip
  224.   \leftskip=0pt \rightskip=0pt}
  225. \def\@changeBaselineskip{\baselineskip=\VDMbaselineskip
  226.   \lineskip=0pt \lineskiplimit=0pt
  227.   % need to alter the size of struts, too
  228.   \setbox\strutbox\hbox{\vrule height.7\baselineskip
  229.       depth.3\baselineskip width\z@}}
  230.  
  231. % these are used in externals, records and cases
  232. \def\@changeLineSeparator{\let\\=\cr} % for usr within \halign
  233. \def\@restoreLineSeparator{\let\\=\newline}
  234.  
  235. \def\@raggedRight{\rightskip=0pt plus 1fil
  236.   \hyphenpenalty=-100 \linepenalty=200
  237.   \binoppenalty=10000 \relpenalty=10000 \pretolerance=-1}
  238.  
  239. %------------------------------------------------------------------------
  240. %
  241. %    Font and Character Changes
  242. %
  243. % make a-zA-Z use the \it family within math mode, and ~ mean \hook.
  244. % Digits 0-9 remain as normal.
  245. \newcount\@mathFamily  \@mathFamily=\itfam
  246. \everymath=\expandafter{\the\everymath\fam\@mathFamily
  247.     \@changeMathmodeCatcodes}
  248. \everydisplay=\expandafter{\the\everydisplay\fam\@mathFamily
  249.     \@changeMathmodeCatcodes}
  250. \mathcode`\0="0030
  251. \mathcode`\1="0031
  252. \mathcode`\2="0032
  253. \mathcode`\3="0033
  254. \mathcode`\4="0034
  255. \mathcode`\5="0035
  256. \mathcode`\6="0036
  257. \mathcode`\7="0037
  258. \mathcode`\8="0038
  259. \mathcode`\9="0039
  260.  
  261. % If the user really wants the normal codes, she can call \defaultMathcodes
  262. \def\defaultMathcodes{\@mathFamily=-1}
  263.  
  264. % make a : into punctuation, a - into a letter, and | mean \mid
  265. \ifps@
  266.  \def\@changeOtherMathcodes{\mathcode`\:="603A \mathcode`\-="002D
  267.   \mathcode`\|="327C \mathchardef\Or="32DA % this is a rel to get 5mu spacing
  268.   \mathcode`\f="0166} % normal letter spacing
  269. \else
  270.  \def\@changeOtherMathcodes{\mathcode`\:="603A \mathcode`\-="042D
  271.   \mathcode`\|="326A \mathchardef\Or="325F }% this is a rel to get 5mu spacing
  272. \fi
  273.  
  274. % alternative underscore
  275. \def\@VDMunderscore{\leavevmode
  276.   \kern.06em\vbox{\hrule\@height .2ex\@width .3em}\penalty\@postUnderPenalty
  277.   \hskip 0.1em}
  278.  
  279. % Allow line breaks after an underscore, but not in vdm mode (see
  280. % \vdm).  This is so long identifiers can be broken when run
  281. % into paragraphs. 
  282. \newcount\@postUnderPenalty \@postUnderPenalty=200
  283.  
  284. % now require some catcode trickery to enable us to change _ when we want to
  285. {\catcode`\_=\active \catcode`\"=\active
  286.  \gdef\@changeGlobalCatcodes{% make _ a normal char
  287.     \catcode`\_=\active \let_=\@VDMunderscore}
  288.  \gdef\@changeMathmodeCatcodes{%
  289.     % make ~ mean \hook, " do text, @ mean subscript
  290.     \let~=\hook
  291.     \catcode`\@=8
  292.     \catcode`\"=\active  \let"=\@mathText}
  293.  \gdef\underscoreoff{% make _ a normal char
  294.     \catcode`\_=\active \let_=\@VDMunderscore}
  295.  \gdef\underscoreon{% restore underscore to usual meaning
  296.     \catcode`\_=8}
  297.  \gdef\@mathText#1"{\hbox{\mathTextFont #1\/}}}
  298.  
  299. \def\mathTextFont{\rm}
  300.  
  301. %----------------------------------------------------------------
  302. %
  303. %    Keywords
  304. %
  305. \ifx\fmtname\@fmtname
  306.     \def\keywordFontBeginSequence{\small\sf}%    user-definable
  307. \else\ifx\fmtname\@psfmtname
  308.     \def\keywordFontBeginSequence{\sf}%    user-definable
  309. \else
  310.     \def\keywordFontBeginSequence{\bf}%    good for SliTeX
  311. \fi\fi
  312.  
  313. \def\kw#1{\hbox{\keywordFontBeginSequence #1\/}}
  314.  
  315. \def\makeNewKeyword#1#2{% use \newcommand for extra checks
  316.     \newcommand{#1}{\hbox{\keywordFontBeginSequence #2\/}}}
  317.  
  318. \makeNewKeyword{\nil}{nil}
  319. \makeNewKeyword{\True}{true}
  320. \makeNewKeyword{\true}{true}
  321. \makeNewKeyword{\False}{false}
  322. \makeNewKeyword{\false}{false}
  323.  
  324. \def\where{\par\moveright\VDMindent\hbox{\keywordFontBeginSequence where\/}}
  325.  
  326. %----------------------------------------------------------------
  327. %
  328. %    monadic operator creation
  329. %
  330. \def\newMonadicOperator#1#2{\newcommand{#1}{\kw{#2\kern.16667em}\nobreak}}
  331.  
  332. %----------------------------------------------------------------
  333. %
  334. %    primitive numeric types
  335. %
  336. % use the AMS fonts for these if possible
  337.  
  338. \ifams@
  339.   \mathchardef\Bool="0\msy@42    % Booleans
  340.   \mathchardef\Nat="0\msy@4E    % Natural numbers
  341.   \def\Nati{\Nat_1}        % Positive natural numbers
  342.   \mathchardef\Int="0\msy@5A    % Integers
  343.   \mathchardef\Real="0\msy@52    % Reals
  344.   \mathchardef\Rat="0\msy@51    % Rationals
  345. \else
  346.   \def\Bool{\hbox{\bf B\/}}
  347.   \def\Nat{\hbox{\bf N\/}}
  348.   \def\Nati{\hbox{$\hbox{\bf N}_1$}}
  349.   \def\Int{\hbox{\bf Z\/}}
  350.   \def\Real{\hbox{\bf R\/}}
  351.   \def\Rat{\hbox{\bf Q\/}}
  352. \fi
  353. \let\Natone=\Nati % just for an alternative
  354.  
  355. %----------------------------------------------------------------
  356. %
  357. %    Operations
  358. %
  359. % The op environment.  Within op you can specify args,
  360. % result, etc. which are gathered into registers, and output when the
  361. % op env. ends.
  362. %
  363. % The optional argument is the operation name
  364.  
  365. % shorthand for an operation on its own: the vdmop env.
  366. \def\vdmop{\vdm\op} \def\endvdmop{\endop\endvdm}
  367.  
  368. % registers constructed within an op environment
  369. \newtoks\@operationName
  370. \newbox\@operationNameBox
  371. \newif\ifArgumentListEncountered@
  372. \newtoks\@argumentListTokens
  373. \newtoks\@resultNameAndTypeTokens
  374. \newbox\@externalsBox
  375. \newbox\@preConditionBox
  376. \newbox\@postConditionBox
  377.  
  378. \def\op{% clear temporaries, deal with optional arg
  379.     \setbox\@operationNameBox=\hbox{}
  380.     \@argumentListTokens={} \ArgumentListEncountered@false
  381.     \@resultNameAndTypeTokens={}
  382.     \setbox\@externalsBox=\box\voidb@x
  383.     \setbox\@preConditionBox=\box\voidb@x
  384.     \setbox\@postConditionBox=\box\voidb@x
  385.     \par\preOperationHook
  386.     \vskip\preOperationSkip
  387.     \@beginVerticalVDM
  388.     \@ifnextchar [{\@opname}{}}
  389.  
  390. % breaking parameters
  391. \newcount\preOperationPenalty \preOperationPenalty=0
  392. \newcount\preExternalPenalty \preExternalPenalty=2000
  393. \newcount\prePreConditionPenalty \prePreConditionPenalty=800
  394. \newcount\prePostConditionPenalty \prePostConditionPenalty=500
  395. \newcount\postOperationPenalty \postOperationPenalty=-500
  396.  
  397. % gaps between bits of operations
  398. \newskip\preOperationSkip \preOperationSkip=2ex plus 0.5ex minus 0.2ex
  399. \newskip\postOperationSkip \postOperationSkip=2ex plus 0.5ex minus 0.2ex
  400. \newskip\postHeaderSkip \postHeaderSkip=.5ex plus .2ex minus .2ex
  401. \newskip\postExternalsSkip \postExternalsSkip=.5ex plus .2ex minus .2ex
  402. \newskip\postPreConditionSkip \postPreConditionSkip=.5ex plus .2ex minus .2ex
  403.  
  404. \def\endop{% make up operation
  405.     % IMPORTANT---don't remove the vskips in this macro
  406.     % if you don't want one, set it to 0pt
  407.     \vskip 0pt
  408.     \@setOperationHeader
  409.     \betweenHeaderAndExternalsHook
  410.     \vskip\postHeaderSkip
  411.     \ifvoid\@externalsBox
  412.           \betweenExternalsAndPreConditionHook
  413.     \else \moveright\VDMindent\box\@externalsBox
  414.           \betweenExternalsAndPreConditionHook
  415.           \vskip\postExternalsSkip
  416.     \fi
  417.     \ifvoid\@preConditionBox
  418.           \betweenPreAndPostConditionHook
  419.     \else \moveright\VDMindent\box\@preConditionBox
  420.           \betweenPreAndPostConditionHook
  421.           \vskip\postPreConditionSkip
  422.     \fi
  423.     \ifvoid\@postConditionBox
  424.           \postOperationHook
  425.     \else \moveright\VDMindent\box\@postConditionBox
  426.           \postOperationHook
  427.           \vskip\postOperationSkip
  428.     \fi}
  429.  
  430. % hooks for user-defined expansion
  431. % TeX is in outer vertical mode when these are called.
  432. % ALWAYS leave TeX in vertical mode after these macros have been called
  433. \def\preOperationHook{\penalty\preOperationPenalty }
  434. \def\betweenHeaderAndExternalsHook{\penalty\preExternalPenalty }
  435. \def\betweenExternalsAndPreConditionHook{\penalty\prePreConditionPenalty }
  436. \def\betweenPreAndPostConditionHook{\penalty\prePostConditionPenalty }
  437. \def\postOperationHook{\penalty\postOperationPenalty }
  438.  
  439. % combine the operation name, argument list and result
  440. \def\@setOperationHeader{%
  441.     \moveright\VDMindent\vtop{%
  442.         \ifArgumentListEncountered@
  443.             \setbox\@operationNameBox=
  444.                 \hbox{\unhbox\@operationNameBox\ $($}\fi
  445.         \hangindent=\wd\@operationNameBox \hangafter=1
  446.         \noindent\kern-.05em\box\@operationNameBox
  447.         \@beginHorizontalVDM
  448.         \ifArgumentListEncountered@\the\@argumentListTokens)\fi
  449.         \ \the\@resultNameAndTypeTokens
  450.         \@endHorizontalVDM}}
  451.  
  452. % set the operation name
  453. % \opname{name-of-operation}
  454. \def\opname#1{\@opname[#1]}
  455. \def\@opname[#1]{\@operationName={#1}%
  456.   \global\setbox\@operationNameBox=\hbox{$\relax#1$\ }}
  457.  
  458. % set up the argument list
  459. % \args{ argument \\ argument \\ argument... } where \\ forces a line break
  460. % This is also used in the fn environment
  461. \def\args{\global\ArgumentListEncountered@true \global\@argumentListTokens=}
  462.  
  463. % result name and type
  464. \def\res{\global\@resultNameAndTypeTokens=}
  465.  
  466. % externals list
  467. %
  468. % An external list could be either very long or very short, so we provide
  469. % two forms.  One is the short \ext{..} command, the other is the externals 
  470. % environment.
  471. % Externals are always separated by \\
  472. %
  473.  
  474. % we have to mess a little to get the catcode of : right
  475. \def\ext{\bgroup\@makeColonActive\@ext}
  476. \def\@ext#1{\externals#1\endexternals\egroup}
  477.  
  478. \def\externals{\global\setbox\@externalsBox=%
  479.     \@beginIndentedPara{\hsize}{ext }{\@setUpExternals}}
  480. \def\endexternals{\@endIndentedPara{\@endAlignment}}
  481.  
  482. \def\@setUpExternals{\@makeColonActive\@changeLineSeparator\@beginAlignment}
  483.  
  484. % more catcode trickery for :
  485. {\catcode`\:=\active
  486.  \gdef\@makeColonActive{\catcode`\:=\active \let:=&}}
  487.  
  488. % the \expandafters are necessary because TeX doesn't expand
  489. % \halign specs when scanning for # and &
  490. \def\@beginAlignment{\expandafter\halign\expandafter\bgroup
  491.     \the\@extAlign\strut\enspace&:\enspace$##$\hfil\cr}
  492. \def\@endAlignment{\crcr\egroup}
  493.  
  494. % the user can decide on the exact alignment of the field names
  495. \newtoks\@extAlign
  496. \def\leftExternals{\@extAlign={$##$\hfil}}
  497. \def\rightExternals{\@extAlign={\hfil$##$}}
  498. \leftExternals
  499.  
  500. \makeNewKeyword{\Rd}{rd } \makeNewKeyword{\Wr}{wr }
  501.  
  502. % pre-condition and post-condition
  503. %
  504. % once again we provide short forms \pre and \post, and environments
  505. % precond and postcond
  506. \def\pre#1{\precond#1\endprecond}
  507. \def\precond{\global\setbox\@preConditionBox=%
  508.     \@beginMathIndentedPara{\hsize}{pre }}
  509. \def\endprecond{\@endMathIndentedPara}
  510.  
  511. \def\post#1{\postcond#1\endpostcond}
  512. \def\postcond{\global\setbox\@postConditionBox=%
  513.     \@beginMathIndentedPara{\hsize}{post }}
  514. \def\endpostcond{\@endMathIndentedPara}
  515.  
  516.  
  517. %----------------------------------------------------------------
  518. %
  519. %    Box man\oe uvres
  520. %
  521. % Here's where all the tricky box manipulation commands go
  522. %
  523. % \@beginIndentedPara begins construction of a \hbox of width #1
  524. % which contains keyword #2 to the left of a para in a vtop.
  525. % #3 is evaluated within the inner vtop.
  526. % endIndentedPara closes the box off; its arg. is evaluated just
  527. % before closing the box.
  528. %
  529. \def\@beginIndentedPara#1#2#3{\hbox to #1\bgroup \setbox0=\kw{#2}%
  530.     \copy0 \strut \vtop\bgroup \advance\hsize by -\wd0 #3}
  531. \def\@endIndentedPara#1{\strut#1\egroup\hss\egroup}
  532.  
  533. % \@beginMathIndentedPara places the para in vdm mode
  534. \def\@beginMathIndentedPara#1#2{\@beginIndentedPara{#1}{#2}%
  535.     {\@beginHorizontalVDM}}
  536. \def\@endMathIndentedPara{\@endIndentedPara{\@endHorizontalVDM}}
  537.  
  538. % \@belowAndIndent#1#2 places #2 in a vbox below and to the right of #1
  539. \def\@belowAndIndent#1#2{#1\hfil\break
  540.     \@beginMathIndentedPara{\hsize}{\qquad}#2\@endMathIndentedPara}
  541.  
  542. %----------------------------------------------------------------
  543. %
  544. %    Constructions
  545. %
  546. % Here are all the standard constructions.
  547. % The only tricky one is \cases.
  548. % Those that construct a box must be made to make that box of 0 width,
  549. % and force a line break immediately afterwards.
  550.  
  551. % \If mm-exp \Then mm-exp \Else mm-exp \Fi
  552. % multi-line indented if-then-else
  553. %
  554. \def\If#1\Then#2\Else#3\Fi{\vtop{%
  555.     \@beginMathIndentedPara{0pt}{if }#1\@endMathIndentedPara
  556.     \@beginMathIndentedPara{0pt}{then }#2\@endMathIndentedPara
  557.     \@beginMathIndentedPara{0pt}{else }#3\@endMathIndentedPara}}
  558.  
  559. % \SIf mm-exp \Then mm-exp \Else mm-exp \Fi
  560. % single line if-then-else
  561. \def\SIf#1\Then#2\Else#3\Fi{\hbox to 0pt{\vtop{\@beginHorizontalVDM
  562.     \kw{if }\nobreak#1\penalty0\hskip 0.5em
  563.     \kw{then }\nobreak#2\penalty-100\hskip 0.5em % break here OK
  564.     \kw{else }\nobreak#3\@endHorizontalVDM}\hss}\hfil\break}
  565.  
  566. % \Let mm-exp \In mm-exp2
  567. % multi-line let..in ; mm-exp2 is `curried'
  568. \def\Let#1\In{\vtop{%
  569.     \@beginMathIndentedPara{0pt}{let }#1\hskip 0.5em
  570.     \kw{in}\@endMathIndentedPara}\hfil\break}
  571.  
  572. % \SLet mm-exp \In mm-exp
  573. % single-line let..in
  574. \def\SLet#1\In#2{\hbox to 0pt{\vtop{\@beginHorizontalVDM
  575.     \kw{let }\nobreak#1\hskip 0.5em
  576.     \kw{in }\penalty-200 #2\@endHorizontalVDM}\hss}\hfil\break}
  577.  
  578. % multi-line cases
  579. % \Cases{ selecting-mm-exp }
  580. % from-case1 & to-case1 \\
  581. % from-case2 & to-case2 \\
  582. %        ...
  583. % from-casen & to-casen
  584. % \Otherwise{ mm-exp }
  585. % \Endcases[optional text for the rest of the line]
  586.  
  587. \newif\ifOtherwiseEncountered@
  588. \newtoks\@OtherwiseTokens
  589.  
  590. \def\Cases#1{\hbox to 0pt\bgroup \vtop\bgroup
  591.         \@beginMathIndentedPara{\hsize}{cases }\strut
  592.             #1\hskip 0.5em\strut\kw{of}%
  593.         \@endMathIndentedPara
  594.         \bgroup % we might be in a nested case, so we have to
  595.             % save the \Otherwise bits we might lose
  596.         \OtherwiseEncountered@false \@changeLineSeparator 
  597.         \@beginCasesAlignment}
  598.  
  599. % the user can decide on the exact alignment
  600. \newtoks\@casesDef
  601. \def\leftCases{\@casesDef={$##$\hfil}}
  602. \def\rightCases{\@casesDef={\hfil$##$}}
  603. \rightCases
  604.  
  605. % the \expandafters are necessary because TeX doesn't expand
  606. % \halign specs when scanning for # and &
  607. \def\@beginCasesAlignment{\expandafter\halign\expandafter\bgroup
  608.     \the\@casesDef&$\,\rightarrow##$\hfil\cr}
  609.  
  610. \def\Otherwise{\global\OtherwiseEncountered@true \global\@OtherwiseTokens=}
  611.  
  612. \def\Endcases{\@endCasesAlignment \@setOtherwise \egroup \@setEndcases}
  613. \def\@endCasesAlignment{\crcr\egroup}
  614. \def\@setOtherwise{\ifOtherwiseEncountered@ % have an otherwise clause
  615.     \@beginMathIndentedPara{\hsize}{otherwise }%
  616.     \strut\the\@OtherwiseTokens\strut
  617.     \@endMathIndentedPara
  618.     \fi}
  619.  
  620. % must test for the optional arg to follow the end
  621. \def\@setEndcases{\noindent
  622.     \strut\kw{end}\@ifnextchar [{\@unbracket}{\@finalCaseEnd}}
  623. \def\@unbracket[#1]{$#1$\@finalCaseEnd}
  624. \def\@finalCaseEnd{\egroup\hss\egroup\hfil\break}
  625.  
  626. %----------------------------------------------------------------
  627. %
  628. %    special symbols
  629.  
  630. % defined as
  631. \ifps@
  632.  \def\DEF{\raise.5ex
  633.     \hbox{\footnotesize\underline{$\mathchar"3\cmsy@34$}}}% a \triangle
  634. \else
  635.  \def\DEF{\raise.5ex
  636.     \hbox{\footnotesize\underline{$\mathchar"3234$}}}% a \triangle
  637. \fi
  638.  
  639. % cross product
  640. \let\x=\times
  641.  
  642. %    logical connectives
  643. %
  644. \def\Iff{\penalty-50\mskip 7mu plus 2mu minus 2mu
  645.     \Leftrightarrow\mskip 7mu plus 2mu minus 2mu}
  646. \let\iff=\Iff
  647. \def\Implies{\penalty-35\mskip 6mu plus 2mu minus 1mu \Rightarrow
  648.     \mskip 6mu plus 2mu minus 1mu}
  649. \let\implies=\Implies
  650. % see changeOtherMathcodes for \Or
  651. \let\And=\land
  652. \let\and=\And
  653. %  use \neg for logical not, or
  654. \let\Not=\neg
  655.  
  656. %    quantification
  657. %
  658. \ifps@
  659.  \mathchardef\Exists="0224
  660.  \mathchardef\Forall="0222
  661.  \mathchardef\suchthat="22D7
  662. \else
  663.  \mathchardef\Exists="0239
  664.  \mathchardef\Forall="0238
  665.  \mathchardef\suchthat="2201
  666. \fi
  667. \def\exists{\@ifstar{\@splitExists}{\@normalExists}}
  668. \ifams@
  669.   \mathchardef\@nexists="0\msy@40 % crossed out existential quantifier
  670. \else
  671.   \def\@nexists{\hbox to 0pt{\raise0.15ex\hbox{/}\hss}\Exists}
  672. \fi
  673. \def\nexists{\@ifstar{\@splitNExists}{\@normalNExists}}
  674. \def\forall{\@ifstar{\@splitForall}{\@normalForall}}
  675. \def\unique{\@ifstar{\@splitUnique}{\@normalUnique}}
  676. \def\uniqueval{\@ifstar{\@splitUniqueval}{\@normalUniqueval}}
  677.  
  678. \def\@normalExists#1#2{{\Exists#1}\suchthat #2}
  679. \def\@normalNExists#1#2{{\@nexists#1}\suchthat #2}
  680. \def\@normalForall#1#2{{\Forall#1}\suchthat #2}
  681. \def\@normalUnique#1#2{{\Exists!\,#1}\suchthat #2}
  682. \def\@normalUniqueval#1#2{{\iota\,#1}\suchthat #2}
  683.  
  684. \def\@splitExists#1{\@belowAndIndent{\Exists#1\suchthat}}
  685. \def\@splitNExists#1{\@belowAndIndent{\@nexists#1\suchthat}}
  686. \def\@splitForall#1{\@belowAndIndent{\Forall#1\suchthat}}
  687. \def\@splitUnique#1{\@belowAndIndent{\Exists!\,#1\suchthat}}
  688. \def\@splitUniqueval#1{\@belowAndIndent{\iota\,#1\suchthat}}
  689.  
  690. %    strachey brackets
  691. %
  692. % (see TeXbook, p.437)
  693. \def\term#1{[\mkern-\thinmuskip[#1\relax]\mkern-\thinmuskip]}
  694.  
  695. %    function composition
  696. %
  697. \let\compf=\circ
  698.  
  699. %----------------------------------------------------------------
  700. %
  701. %    function environment
  702. %
  703. % This environment is similar to the op environment, but is used for
  704. % function definition.  
  705. %
  706. % The mandatory first parameter is the name of the function, the
  707. % second is the argument list.
  708. %
  709. % The *-form simply doesn't force the parentheses round the argument list
  710.  
  711. \def\fn{\parens@true\@beginVDMfunction}
  712. \@namedef{fn*}{\parens@false\@beginVDMfunction}
  713. \@namedef{endfn*}{\endfn}
  714.  
  715. % short form
  716. \def\vdmfn{\vdm\parens@true \@beginVDMfunction}
  717. \def\endvdmfn{\endfn\endvdm}
  718. \@namedef{vdmfn*}{\vdm\parens@false \@beginVDMfunction}
  719. \@namedef{endvdmfn*}{\endfn\endvdm}
  720.  
  721. % registers used within the fn environment
  722. \newtoks\@fnName
  723. \newbox\@fnNameBox
  724. \newif\ifsignatureEncountered@
  725. \newtoks\@signatureTokens
  726. \newbox\@fnDefnBox
  727. \newif\ifparens@
  728.  
  729. \def\@beginVDMfunction#1#2{%
  730.     \@fnName={#1}
  731.     \setbox\@fnNameBox=\hbox{$#1$}%
  732.     \setbox\@preConditionBox=\box\voidb@x % for people who want to do
  733.     \setbox\@postConditionBox=\box\voidb@x% implicit defns
  734.     \@signatureTokens={}\signatureEncountered@false
  735.     \ifparens@
  736.         \@argumentListTokens={(#2)}%
  737.     \else
  738.         \@argumentListTokens={#2}%
  739.     \fi
  740.     \par\preFunctionHook
  741.     \vskip\preFunctionSkip
  742.     \@beginVerticalVDM 
  743.     \@beginFnDefn}
  744.  
  745. % read in a signature
  746. \def\signature{\global\signatureEncountered@true \global\@signatureTokens=}
  747.  
  748. \def\@beginFnDefn{\global\setbox\@fnDefnBox=\vtop\bgroup
  749.     \hangindent=2em \hangafter=1 \@beginHorizontalVDM
  750.     \advance\hsize by-2em % this fools vboxes within the
  751.     % function body about the hanging indent...yuk.
  752.     % If you change the size of the indent, change the
  753.     % corresponding line in \endfn.
  754.     \copy\@fnNameBox \the\@argumentListTokens 
  755.     \quad\DEF\penalty-100\quad }
  756.  
  757. \newskip\preFunctionSkip \preFunctionSkip=2ex plus .5ex minus .2ex
  758. \newskip\postFunctionSkip \postFunctionSkip=2ex plus .5ex minus .2ex
  759. \newskip\betweenSignatureAndBodySkip
  760. \betweenSignatureAndBodySkip=1.2ex plus .3ex minus .2ex
  761. \newskip\betweenFunctionAndPreSkip
  762. \betweenFunctionAndPreSkip=1.2ex plus .3ex minus .2ex
  763.  
  764. \def\endfn{%
  765.     \advance\hsize by 2em% matches the dirty \advance in \@beginFnDefn
  766.     \@endHorizontalVDM
  767.     \egroup  % this ends the vtop we started in \@beginFnDefn
  768.     \ifsignatureEncountered@
  769.         \setbox0=\hbox{\unhbox\@fnNameBox$\;\mathpunct:\,$}%
  770.         \dimen255=\wd0 \noindent \box0
  771.         \vtop{\advance\hsize by-\dimen255 \@beginHorizontalVDM
  772.             \the\@signatureTokens \@endHorizontalVDM}\par
  773.         \betweenSignatureAndBodyHook
  774.         \vskip\betweenSignatureAndBodySkip
  775.     \fi
  776.     \moveright\VDMindent\box\@fnDefnBox
  777.     \ifvoid\@preConditionBox
  778.           \betweenPreAndPostConditionHook
  779.           \vskip\postFunctionSkip
  780.     \else \betweenFunctionAndPreHook
  781.           \vskip\betweenFunctionAndPreSkip
  782.           \moveright\VDMindent\box\@preConditionBox
  783.           \betweenPreAndPostConditionHook
  784.           \vskip\postPreConditionSkip
  785.     \fi
  786.     \ifvoid\@postConditionBox
  787.           \postFunctionHook
  788.     \else \moveright\VDMindent\box\@postConditionBox
  789.           \postFunctionHook
  790.           \vskip\postOperationSkip
  791.     \fi}
  792.  
  793. \newcount\preFunctionPenalty \preFunctionPenalty=0
  794. \newcount\betweenSignatureAndBodyPenalty \betweenSignatureAndBodyPenalty=500
  795. \newcount\betweenFunctionAndPrePenalty \betweenFunctionAndPrePenalty=1000
  796. \newcount\postFunctionPenalty \postFunctionPenalty=-500
  797.  
  798. % These are called in outer vertical mode---they must also exit in this mode
  799. \def\preFunctionHook{\penalty\preFunctionPenalty }
  800. \def\betweenSignatureAndBodyHook{\penalty\betweenSignatureAndBodyPenalty }
  801. \def\betweenFunctionAndPreHook{\penalty\betweenFunctionAndPrePenalty }
  802. \def\postFunctionHook{\penalty\postFunctionPenalty }
  803.  
  804. %    other function-related things
  805. %
  806.  
  807. % function arrow
  808. \def\to{\penalty-100\rightarrow}
  809.  
  810. % explicit lamdba function
  811. \def\LambdaFn{\@ifstar{\@splitLambdaFn}{\@normalLambdaFn}}
  812. \def\@normalLambdaFn#1#2{{\lambda#1}\suchthat#2}
  813. \def\@splitLambdaFn#1#2{% place body in a separate box below and to the right
  814.     {\lambda#1}\suchthat\hfil\break
  815.     \@beginMathIndentedPara{\hsize}{\qquad}#2\@endMathIndentedPara}
  816.  
  817. %----------------------------------------------------------------
  818. %
  819. %    Sets
  820.  
  821. % new set type
  822. \def\setof#1{\kw{set of }#1}
  823.  
  824. % set enumeration
  825. \def\set#1{\{#1\}}
  826.  
  827. % empty set
  828. \def\emptyset{\{\,\}}
  829.  
  830. % usual LaTeX operators apply: \in \notin \subset \subseteq
  831. \let\inter=\cap \let\intersection=\inter
  832. \let\Inter=\bigcap \let\Intersection=\Inter
  833. \let\union=\cup
  834. \let\Union=\bigcup
  835. \ifps@
  836.  \mathchardef\minus="222D
  837. \else
  838.  \mathchardef\minus="2200
  839. \fi
  840. \def\diff{\minus} \let\difference=\diff
  841.  
  842. \newMonadicOperator{\card}{card}
  843. \newMonadicOperator{\Min}{min}
  844. \newMonadicOperator{\Max}{max}
  845.  
  846. %----------------------------------------------------------------
  847. %
  848. %     Map type
  849.  
  850. % new map type
  851. \def\mapof#1#2{\kw{map }\nobreak#1\penalty-50\hskip .3em \kw{to }\nobreak#2}
  852.  
  853. % one-one map
  854. \def\mapinto#1#2{\kw{map }\nobreak#1\penalty-50
  855.     \hskip .3em \kw{into }\nobreak#2}
  856.  
  857. % map enumeration
  858. \def\map#1{\{#1\}}
  859.  
  860. % empty map
  861. \def\emptymap{\{\,\}}
  862.  
  863. %    map operators
  864. %
  865. % use \mapsto for |->
  866. % overwrite
  867. \def\owr{\dagger}
  868.  
  869. \ifams@
  870.   % domain restriction
  871.   \mathchardef\dres="2\msx@43
  872.   % range restriction
  873.   \mathchardef\rres="2\msx@42 % the right hand version
  874. \else % for those without AMS fonts
  875.   \let\dres=\lhd
  876.   \let\rres=\rhd
  877. \fi
  878.  
  879. % domain subtraction
  880. \ifps@
  881.  \def\dsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu\dres$}}}
  882. \else
  883.  \def\dsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu
  884.     \lower.1ex\hbox{$\dres$}$}}}
  885. \fi
  886.  
  887. % range subtraction
  888. \ifps@
  889.  \def\rsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu\rres$}}}
  890. \else
  891.  \def\rsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu
  892.     \lower.1ex\hbox{$\rres$}$}}}
  893. \fi
  894.  
  895. \newMonadicOperator{\dom}{dom}
  896. \newMonadicOperator{\rng}{rng}
  897.  
  898. %----------------------------------------------------------------
  899. %
  900. %    Sequences
  901. %
  902.  
  903. % new type
  904. \def\seqof#1{\kw{seq of }#1}
  905.  
  906. % enumeration
  907. \def\seq#1{[#1]}
  908.  
  909. % empty sequence
  910. \def\emptyseq{[\,]}
  911.  
  912. \newMonadicOperator{\len}{len}
  913. \newMonadicOperator{\hd}{hd}
  914. \newMonadicOperator{\tl}{tl}
  915. \newMonadicOperator{\elems}{elems}
  916. \newMonadicOperator{\inds}{inds}
  917. \def\cons#1{\kw{cons}\nobreak(#1)}
  918.  
  919. % sequence concatenation
  920. \ifams@
  921.   \mathchardef\sconc="2\msy@79
  922. \else
  923.   % this is truly yukky
  924.   \def\sconc{\mathbin{\hbox{\raise1ex\hbox{$\frown$}\kern-0.47em
  925.     \raise0.2ex\hbox{\it\char"12}}}}
  926. \fi
  927.  
  928. % distributed concatenation
  929. \newMonadicOperator{\Conc}{conc}
  930.  
  931. %----------------------------------------------------------------
  932. %
  933. %    type equation
  934. %
  935. \newtoks\@typeName
  936. \def\type#1#2{{\@typeName{#1} \preTypeHook \vskip\preTypeSkip
  937.     \@beginVerticalVDM
  938.     \moveright\VDMindent\vtop{\@beginHorizontalVDM #1=#2
  939.         \@endHorizontalVDM}
  940.     \postTypeHook \vskip\postTypeSkip}}
  941.  
  942. \def\preTypeHook{} \def\postTypeHook{}
  943. \newskip\preTypeSkip \preTypeSkip=1.2ex plus .5ex minus .3ex
  944. \newskip\postTypeSkip \postTypeSkip=1.2ex plus .5ex minus .3ex
  945.  
  946. %----------------------------------------------------------------
  947. %
  948. %    Composite Objects
  949. %
  950.  
  951. % literal composition; we have a compose and a composite env.
  952.  
  953. % single line compose
  954. \@namedef{composite*}#1{\kw{compose }$\relax#1\relax$\kw{ of }$\relax}
  955. \@namedef{endcomposite*}{\relax$\kw{ end}}
  956.  
  957. % multiple line version
  958. \def\composite#1{\bgroup\vskip\preCompositeSkip
  959.     \@beginVerticalVDM
  960.     \moveright\VDMindent\vtop\bgroup
  961.     \@beginHorizontalVDM
  962.     \kw{compose }#1\kw{ of}%\hfil\break
  963.     \@endHorizontalVDM
  964.     \@makeColonActive\@changeLineSeparator
  965.     \expandafter\halign\expandafter\bgroup\expandafter\qquad
  966.         \the\@recordAlign\strut\enspace&:\enspace$##$\hfil\cr}
  967. \def\endcomposite{\crcr\egroup % closes \halign
  968.     \kw{end}\egroup % ends the \vtop
  969.     \vskip\postCompositeSkip\egroup}
  970.  
  971. \def\scompose#1#2{\@nameuse{composite*}{#1}{#2}\@nameuse{endcomposite*}}
  972.  
  973. \newskip\preCompositeSkip \preCompositeSkip=1.2ex plus .5ex minus .3ex
  974. \newskip\postCompositeSkip \postCompositeSkip=1.2ex plus .5ex minus .3ex
  975.  
  976. % record composites; likewise we have a short and a long form
  977. \newtoks\@recordName
  978.  
  979. \def\record#1{\@recordName{#1}
  980.   \par\preRecordHook
  981.   \vskip\preRecordSkip
  982.   \@beginVerticalVDM
  983.   \moveright\VDMindent\hbox\bgroup
  984.       \setbox0=\hbox{$#1$\enspace::\enspace}%
  985.       \@makeColonActive\@changeLineSeparator
  986.       \advance\hsize by-\wd0 \box0
  987.       \@restoreMargins
  988.       %
  989.       % the \expandafters are necessary because TeX doesn't expand
  990.       % \halign specs when scanning for # and &
  991.       \vtop\bgroup\expandafter\halign\expandafter\bgroup
  992.           \the\@recordAlign\strut\enspace&:\enspace$##$\hfil\cr}
  993.  
  994. \def\endrecord{\crcr\egroup% closes halign
  995.     \egroup% closes vtop
  996.     \egroup% closes hbox
  997.     \par\postRecordHook
  998.     \vskip\postRecordSkip}
  999.  
  1000. % the user can decide on the exact alignment of the field names
  1001. \newtoks\@recordAlign
  1002. \def\leftRecord{\@recordAlign={$##$\hfil}}
  1003. \def\rightRecord{\@recordAlign={\hfil$##$}}
  1004. \rightRecord
  1005.  
  1006. % more catcode trickery
  1007. \def\defrecord{\bgroup\@makeColonActive\@defrecord}
  1008. \def\@defrecord#1#2{\record{#1}#2\endrecord\egroup}
  1009.  
  1010. \newskip\preRecordSkip \preRecordSkip=.75ex plus .3ex minus .2ex
  1011. \newskip\postRecordSkip \postRecordSkip=.75ex plus .3ex minus .2ex
  1012. \newcount\preRecordPenalty \preRecordPenalty=0
  1013. \newcount\postRecordPenalty \postRecordPenalty=-100
  1014. \def\preRecordHook{\penalty\preRecordPenalty }
  1015. \def\postRecordHook{\penalty\postRecordPenalty }
  1016.  
  1017. % \chg: mu function on composites
  1018. \def\chg#1#2#3{\mu(#1,#2\mapsto#3)}
  1019.  
  1020. %----------------------------------------------------------------
  1021. %
  1022. %    Hooks
  1023. %
  1024. % hooked identifiers --- these are taken from the TeXbook, p.357, 359
  1025. \ifps@
  1026.  \def\leftharpoonupfill{$\m@th \mathord\leftharpoonup \mkern-6mu
  1027.   \cleaders\hbox{$\mkern-2mu \mathchar"0\cmsy@00 \mkern-2mu$}\hfill
  1028.   \mkern-6mu \mathchar"0\cmsy@00$}  % p.357, \leftarrowfill
  1029. \else
  1030.  \def\leftharpoonupfill{$\m@th \mathord\leftharpoonup \mkern-6mu
  1031.   \cleaders\hbox{$\mkern-2mu \mathord\minus \mkern-2mu$}\hfill
  1032.   \mkern-6mu \mathord\minus$}  % p.357, \leftarrowfill
  1033. \fi
  1034. \def\overleftharpoonup#1{{%
  1035.   \boxmaxdepth=\maxdimen % this fixes Lamport's figures, but isn't necessary
  1036.                % for versions after 15 Dec 87
  1037.   \vbox{\ialign{##\crcr % p.359, \overleftarrow
  1038.     \leftharpoonupfill\crcr\noalign{\kern-\p@\nointerlineskip}
  1039.     $\hfil\displaystyle{#1}\hfil$\crcr}}}}
  1040.  
  1041. \let\hook=\overleftharpoonup  % c'est simple comme bonjour
  1042.  
  1043. %-----------------------------------------------------------------
  1044. %
  1045. %     General formula environment, a bit like \[ \] but is
  1046. %    indented to \VDMindent and will take \\
  1047. %
  1048. %
  1049. \def\form#1{\formula #1\endformula}
  1050.  
  1051. \def\formula{\par\preFormulaHook
  1052.     \vskip\preFormulaSkip
  1053.     \@beginVerticalVDM
  1054.     \bgroup
  1055.     \moveright\VDMindent\vtop\bgroup\@beginHorizontalVDM}
  1056. \def\endformula{\@endHorizontalVDM\egroup % ends the vtop
  1057.     \egroup % ends the overall group
  1058.     \par\postFormulaHook
  1059.     \vskip\postFormulaSkip}
  1060.  
  1061. \newskip\preFormulaSkip \preFormulaSkip=1.2ex plus .5ex minus .3ex
  1062. \newskip\postFormulaSkip \postFormulaSkip=1.2ex plus .5ex minus .3ex
  1063. \newcount\preFormulaPenalty \preFormulaPenalty=0
  1064. \newcount\postFormulaPenalty \postFormulaPenalty=-100
  1065. \def\preFormulaHook{\penalty\preFormulaPenalty }
  1066. \def\postFormulaHook{\penalty\postFormulaPenalty }
  1067.  
  1068. %----------------------------------------------------------------
  1069. %
  1070. %    Formula within a box, when width is unknown
  1071. %
  1072. %    equivalent to \parbox[t]{\hsize}{\@beginHorizontalVDM
  1073. %        ...\@endHorizontalVDM}
  1074. %
  1075. \def\formbox{\vtop\bgroup\@beginHorizontalVDM}
  1076. \def\endformbox{\strut\@endHorizontalVDM\egroup}
  1077.  
  1078. %----------------------------------------------------------------
  1079. %
  1080. %    special font for constants
  1081. %
  1082. \def\constantFont{\sc}
  1083. \def\const#1{\hbox{\constantFont #1\/}}
  1084.  
  1085. %----------------------------------------------------------------
  1086. %
  1087. %    line break and indent
  1088. %
  1089. \def\T#1{\\\hbox to #1em{}}
  1090.  
  1091. %----------------------------------------------------------------
  1092. %
  1093. %    line break and push line after to RHS
  1094. %
  1095. \def\R{\\\hspace*{\fill}}
  1096.  
  1097. %----------------------------------------------------------------
  1098. %
  1099. %    Proofs
  1100. %
  1101. % a proof environment for typesetting proofs in the "natural
  1102. % deduction" style.
  1103.  
  1104. \newdimen\ProofIndent \ProofIndent=\VDMindent
  1105. \newdimen\ProofNumberWidth \ProofNumberWidth=\parindent
  1106.  
  1107. \def\proof{\par\preProofHook
  1108.     \vskip\preProofSkip
  1109.     \let\&=\@proofLine
  1110.     \moveright\ProofIndent\vtop\bgroup
  1111.         \@indentLevel=1
  1112.         \advance\linewidth by-\ProofIndent
  1113.         \begin{tabbing}%
  1114.         \hbox to\ProofNumberWidth{}\=\kill}    % template line
  1115. \def\endproof{\end{tabbing}\advance\linewidth by\ProofIndent
  1116.     \egroup % ends the \vtop
  1117.     \par\postProofHook
  1118.     \vskip\postProofSkip}
  1119.  
  1120. \newskip\preProofSkip \preProofSkip=1.2ex plus .5ex minus .3ex
  1121. \newskip\postProofSkip \postProofSkip=1.2ex plus .5ex minus .3ex
  1122.  
  1123. \newcount\preProofPenalty \preProofPenalty=-100
  1124. \newcount\postProofPenalty \postProofPenalty=0
  1125. \def\preProofHook{\penalty\preProofPenalty }
  1126. \def\postProofHook{\penalty\postProofPenalty }
  1127.  
  1128. \def\From{\@indentProof\kw{from }\=%
  1129.     \global\advance\@indentLevel by 1
  1130.     \@enterMathMode}
  1131. \def\Infer{\global\advance\@indentLevel by-1
  1132.     \@indentProof\kw{infer }\@enterMathMode}
  1133. \def\@proofLine{\@indentProof\@enterMathMode}
  1134. \def\by{\`}
  1135.  
  1136. \newcount\@indentLevel
  1137. \newcount\@indentCount
  1138. \def\@indentProof{% do \>, \@indentLevel times
  1139.     \global\@indentCount=\@indentLevel
  1140.     \@gloop \>\global\advance\@indentCount by-1
  1141.     \ifnum\@indentCount>0
  1142.     \repeat}
  1143.  
  1144. % need special loop macros that works in across boxes
  1145. \def\@gloop#1\repeat{\gdef\@body{#1}\@giterate}
  1146. \def\@giterate{\@body \global\let\@gloopNext=\@giterate
  1147.     \else \global\let\@gloopNext=\relax \fi \@gloopNext}
  1148.  
  1149. % this enters math mode and sets the LaTeX macros \@stopfield up
  1150. % to exit math mode
  1151. \def\@enterMathMode{\def\@stopfield{$\egroup}$}
  1152.  
  1153. %----------------------------------------------------------------
  1154. \def\VDMauthor{M.Wolczko,
  1155. CS Dept.,
  1156. Univ. of Manchester, UK. 
  1157. mario@uk.ac.man.cs.ux
  1158. mcvax!man.cs.r5!mario}
  1159.  
  1160. \def\VDMversion{2.5}
  1161.  
  1162. \typeout{vdm style option <25 Mar 88>}
  1163. %----------------------------------------------------------------
  1164. %
  1165. %    Global changes
  1166. %
  1167. % All things that have to be invoked before the user's stuff appears
  1168. % should go here.
  1169. %
  1170. % by default the math spacing and changes to @ and _ apply everywhere
  1171. \@changeOtherMathcodes \@changeGlobalCatcodes
  1172. %
  1173. %-------------------the end--------------------------------------
  1174. \endinput
  1175. %
  1176. %    Summary of penalties
  1177. %
  1178. %    Penalties in vertical mode
  1179. %
  1180. % \preOperationPenalty        before an op begins
  1181. % \preExternalPenalty        between the header and externals of an op
  1182. % \prePreConditionPenalty    before the precondition
  1183. % \prePostConditionPenalty    before the postcondition
  1184. % \postOperationPenalty        at the end of an op
  1185. %
  1186. % \preFunctionPenalty        before a fn begins
  1187. % \betweenSignatureAndBodyPenalty 
  1188. % \postFunctionPenalty        after a fn ends
  1189. %
  1190. % \preRecordPenalty        before a record
  1191. % \postRecordPenalty        after a record
  1192. %
  1193. %    etc for formula, proof
  1194. %
  1195. %    Penalties in horizontal mode in boxes
  1196. %
  1197. % \linepenalty            101        \@raggedRight
  1198. % `if mm-exp ^ then..'        0        \SIf
  1199. % `if ... then mm-exp ^ else'    -100        \SIf
  1200. % `let mm-exp in ^ ...'        -200        \SLet
  1201. % `map mm-exp ^ to ...'        -50        \map
  1202. % ^\iff                -50        \iff
  1203. % ^\implies            -35        \implies
  1204. % func(args) \DEF^        -100        \begin{fn}
  1205. % \binoppenalty            10000
  1206. % \relpenalty            10000
  1207. % \hyphenpenalty        -100        \suchthat
  1208. % ^\to                -100        \to
  1209. % _^                100        \@VDMunderscore
  1210. %
  1211.